package io.gitee.zhucan123.core.infrastructure.annotation;


import com.niimbot.middlend.core.infrastructure.dataconversion.IntegerEnum;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.Name;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.Writer;
import java.util.Collections;
import java.util.Set;

/**
 * @author: zhuCan
 * @date: 2019/10/16 14:40
 * @description: 枚举db.sql 生成器
 */
//@AutoService(Processor.class)  //自动注册
public class EnumFlywayDBFileCreator extends AbstractProcessor {

  private Filer filer;
  private Messager messager;
  private Elements elementUtils;


  @Override
  public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    filer = processingEnv.getFiler();
    messager = processingEnvironment.getMessager();
    elementUtils = processingEnvironment.getElementUtils();
  }

  @Override
  public Set<String> getSupportedAnnotationTypes() {
    return Collections.singleton(FlywayInitializer.class.getCanonicalName());
  }

  @Override
  public SourceVersion getSupportedSourceVersion() {
    return SourceVersion.latestSupported();
  }

  @Override
  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    System.err.println("Processor : " + getClass().getSimpleName());
    long start = System.currentTimeMillis();
    for (TypeElement annotation : annotations) {
      for (Element element : roundEnv.getElementsAnnotatedWith(annotation)) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "found @Log at " + element);
      }
    }

    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(FlywayInitializer.class);

    StringBuffer sql = new StringBuffer("use order_form ;\n");
    //获取当前时间
    //String date = DateHandler.formaFulltDate();
    String date = "2012-12-12 12:12:12";


    elements.forEach(x -> {
      PackageElement packageElement = elementUtils.getPackageOf(x);
      String packageName = packageElement.getQualifiedName().toString();
      // 被扫描的类名
      Name simpleName = x.getSimpleName();

      // sql
      FlywayInitializer flywayInitializer = x.getAnnotation(FlywayInitializer.class);
      try {
        Class<?> clazz = Class.forName(packageName + "." + simpleName);
        if (IntegerEnum.class.isAssignableFrom(clazz) && clazz.isEnum()) {
          IntegerEnum[] enumConstants = (IntegerEnum[]) clazz.getEnumConstants();
          sql.append("truncate " + flywayInitializer.table() + ";\n");
          sql.append("insert into ");
          sql.append(flywayInitializer.table());
          sql.append("(");
          sql.append(flywayInitializer.codeColumn());
          sql.append(",");
          sql.append(flywayInitializer.valueColumn());
          sql.append(",gmt_create,gmt_modified)");
          sql.append(" values \n");

          for (IntegerEnum anEnum : enumConstants) {
            sql.append("(");
            sql.append(anEnum.getValue());
            sql.append(",'");
            sql.append(anEnum.attributeName());
            sql.append("','").append("now()").append("','").append("now()").append("'),\n");

          }
          sql.deleteCharAt(sql.length() - 2);
          sql.append(";\n");
        }

      } catch (ClassNotFoundException e) {
        e.printStackTrace();
      }


    });
    System.out.println(sql.toString());
    try {
      if (!elements.isEmpty()) {
        FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "V13_init.sql");
        Writer writer = resource.openWriter();
        writer.write(sql.toString());
        writer.flush();
        writer.close();

      }


    } catch (IOException e) {
      e.printStackTrace();
    }
    System.out.println("耗时 : " + (System.currentTimeMillis() - start) + " 毫秒");
    return true;
  }
}

